<script setup>
import {
  onMounted,
  onUnmounted,
  reactive,
  useTemplateRef,
  nextTick,
  toRef,
} from 'vue';
import { useDebounceValue } from '@/hooks/useDebounce';
import axios from 'axios';
defineOptions({
  name: 'YIconView',
});

const emit = defineEmits(['click']);

const iconContentRef = useTemplateRef('iconContent');
const iconContainerSize = 74;


const data = reactive({
  searchKeyword: '',
  currentPage: 1,
  pageSize: 10,
  total: 0,
  icons: [],
  cols: 0,
  rows: 0,
});

// 使用防抖hook处理搜索关键词
const { debouncedValue: debounceSearchKeyword } = useDebounceValue(
  toRef(data, 'searchKeyword'),
  (newValue) => {
    data.currentPage = 1; // 防抖搜索时重置到第一页
  },
  300, // 300ms防抖延迟
);

const filteredIcons = computed(() => {
  if (!debounceSearchKeyword.value) {
    return data.icons;
  }
  return data.icons.filter((icon) =>
    icon.className
      .toLowerCase()
      .includes(debounceSearchKeyword.value.toLowerCase()),
  );
});

const pageIcons = computed(() => {
  const start = (data.currentPage - 1) * data.pageSize;
  const end = start + data.pageSize;

  data.total = filteredIcons.value.length; //总图标数量

  return filteredIcons.value.slice(start, end);
});
const gridStyle = computed(() => {
  return {
    display: 'grid',
    gridTemplateColumns: `repeat(${data.cols}, ${iconContainerSize}px)`,
    gridTemplateRows: `repeat(${data.rows}, ${iconContainerSize}px)`,
    gap: `0px`,
    justifyContent: 'space-between',
  };
});

function initIcons() {
  const reg = /\.fa-[a-zA-Z0-9-]+[{]/g;
  axios.get('/public/fontawesome/css/all.min.css').then((res) => {
    const icons = res.data.match(reg);
    icons.map((t, index) => {
      if (index >= 47 && index < 1452) {
        data.icons.push({
          className: `fa-solid ${t.slice(1, -1)}`,
        });
      } else if (index >= 1452 && index < icons.length - 1) {
        data.icons.push({
          className: `fa-brands ${t.slice(1, -1)}`,
        });
      }
    });
  });
}

function calculateLayout() {
  if (!iconContentRef.value) {
    return;
  }
  const container = iconContentRef.value;
  const containerWidth = container.clientWidth;
  const containerHeight = container.clientHeight;

  const col = Math.floor(containerWidth / iconContainerSize);
  const row = Math.floor(containerHeight / iconContainerSize);

  data.cols = col;
  data.rows = row;

  data.pageSize = col * row; //每页图标数量
}

const handleClick = async (className) => {
  emit('click', className);
};

{
  // 监听窗口大小变化
  function handleResize() {
    nextTick(() => {
      calculateLayout();
    });
  }
  // 监听容器大小变化（使用ResizeObserver）
  const resizeObserver = new ResizeObserver(() => {
    handleResize();
  });

  onMounted(() => {
    if (iconContentRef.value) {
      resizeObserver.observe(iconContentRef.value);
    }
    initIcons();
  });

  onUnmounted(() => {
    if (iconContentRef.value) {
      resizeObserver.unobserve(iconContentRef.value);
    }
    resizeObserver.disconnect();
  });
}
</script>

<template>
  <div class="y-icon-view wh-full flex flex-col">
    <div class="y-icon-view-header p-2">
      <div class="y-icon-view-header-left">
        <div class="y-icon-view-header-left-search flex items-center">
          <a-input
            v-model:value="data.searchKeyword"
            placeholder="搜索图标..."
            style="max-width: 300px"
            allowClear
          />
        </div>
      </div>
    </div>

    <div ref="iconContent" class="y-icon-view-content flex-1 overflow-hidden">
      <div class="y-icon-view-content-list" :style="gridStyle">
        <div
          class="y-icon-view-content-list-item p-2"
          v-for="icon in pageIcons"
          :key="icon.className"
        >
          <div
            class="y-icon-view-content-list-item-icon cursor-pointer"
            un-wh-full
            un-flex
            un-items-center
            un-justify-center
            un-border="1px solid"
            un-rounded="lg"
            @click="handleClick(icon.className)"
          >
            <y-icon
              :icon="icon.className"
              class="font-size-6"
              style="color: inherit"
            />
          </div>
        </div>
      </div>
    </div>

    <div class="y-icon-view-footer text-right">
      <a-pagination
        :total="data.total"
        v-model:current="data.currentPage"
        :pageSize="data.pageSize"
        :showSizeChanger="false"
        :show-total="(total) => `总数 ${total} 条, 每页 ${data.pageSize} 条`"
      />
    </div>
  </div>
</template>

<style scoped>
.y-icon-view-content-list-item-icon {
  border-color: var(--theme-border);
  &:hover {
    transition: scale 0.3s ease-in-out;
    transform: scale(1.1);
    color: var(--color-primary);
  }
}
</style>
